/*
 ============================================================================
 Name        : main.c
 Author      : dogguo
 Time        : 2016/05/01 23:59
 Version     : V0.0.1
 Copyright   : WifiShare Cooperation
 Description : WL APP
 ============================================================================
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <pthread.h>
#include "app/gconstant.h"
#include "task.h"
#include "rps.h"
#include "lib/cjson/cJSON.h"
#include "lib/util/convert.h"
#include "lib/util/util.h"
#include "lib/util/util_sqlite.h"
#include "app/gvar.h"
#include "network.h"
/* socket init */
#define SOCKET_SERVER_PORT  12347
#define SOCKET_CLIENT_NUM   20
int socket_fd;
int socket_conn_fd;
struct sockaddr_in socketaddr_client;
struct sockaddr_in socketaddr_server;
socklen_t socketaddr_client_len = sizeof(socketaddr_client);

/* socket process */
char* rmdt_buf;// remain data_buffer
char  recvdt_buf[1024];// socket recv data buffer
char* rpsdt_buf;// socket rps data buffer
char* prtdt_buf;// protocol data buffer
char* cmddt_buf;
int recvdt_len = 0;
int rpsdt_len = 0;
int prtdt_len = 0;
int rmdt_len = 0;
int cmddt_len = 0;

/* socket rps */
char rpsdt_header_buf[2] = {0x06, 0xA1};
char rpsdt_remain_buf[10] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
char rpsdt_jdtlen_buf[4] = {0x00, 0x00, 0x00, 0x00};



typedef struct {
    char* user_name;
    char* user_mac;

} Deviceulist;


/* reponse error */
int rps_cmd_error(int cmd_id, int err_code, char* err_msg) {
    printf("rps_cmd_error <<<--- \n");

    char* rps = NULL;
    switch (cmd_id) {
        case 1: {
            rps = get_rps_error(1, "sendMasterInfo", "1.0", err_code, err_msg);
            printf("rps_cmd_error <<<--- rps = %s \n", rps);
            if(rps == NULL) {
                printf("rps_cmd_error <<<--- rps is NULL get_rps_error failed ! \n");
                return 0;
            }
        }
        break;
        case 2: {
            rps = get_rps_error(2, "sendWifiInfo", "1.0", err_code, err_msg);
            printf("rps_cmd_error <<<--- rps = %s \n", rps);
            if(rps == NULL) {
                printf("rps_cmd_error <<<--- rps is NULL get_rps_error failed ! \n");
                return 0;
            }
        }
        break;
        case 3: {
            rps = get_rps_error(3, "modifyDeviceWifi", "1.0", err_code, err_msg);
            printf("rps_cmd_error <<<--- rps = %s \n", rps);
            if(rps == NULL) {
                printf("rps_cmd_error <<<--- rps is NULL get_rps_error failed ! \n");
                return 0;
            }
        }
        break;
        case 4: {
            rps = get_rps_error(4, "getDeviceUserList", "1.0", err_code, err_msg);
            printf("rps_cmd_error <<<--- rps = %s \n", rps);
            if(rps == NULL) {
                printf("rps_cmd_error <<<--- rps is NULL get_rps_error failed ! \n");
                return 0;
            }
        }
        break;
        case 5: {
            rps = get_rps_error(5, "deleteDeviceUser", "1.0", err_code, err_msg);
            printf("rps_cmd_error <<<--- rps = %s \n", rps);
            if(rps == NULL) {
                printf("rps_cmd_error <<<--- rps is NULL get_rps_error failed ! \n");
                return 0;
            }
        }
        break;
        default:
            return 0;
    }


    int jdt_len = strlen(rps);
    dec_2_hex_big(jdt_len, rpsdt_jdtlen_buf, 4);

    rpsdt_len = 16 + jdt_len;
    rpsdt_buf = (char*) malloc(rpsdt_len);
    arr_char_pcpy(rpsdt_buf, 0, rpsdt_header_buf, 2);
    arr_char_pcpy(rpsdt_buf, 2, rpsdt_remain_buf, 10);
    arr_char_pcpy(rpsdt_buf, 12, rpsdt_jdtlen_buf, 4);
    arr_char_pcpy(rpsdt_buf, 16, rps, jdt_len);
//    prt_arr_char(rpsdt_buf, rpsdt_len, 1, "rps_do <<<--- rpsdt_buf = ", HEX_02X);

    int r = send(socket_conn_fd, rpsdt_buf, rpsdt_len, 0);
    printf("rps_cmd_error <<<--- send socket_conn_fd r = %d \n", r);
    if(r < 0) {
        printf("rps_cmd_error <<<--- send failed ! \n");
        return 0;
    }
    free(rpsdt_buf);

    printf("rps_cmd_error --->>> \n");
    return 1;
}


/* reponse success */
int rps_cmd_succ(int cmd_id) {
    printf("rps_cmd_succ <<<--- \n");

    char* rps = NULL;
    switch (cmd_id) {
        case 1: {
            rps = get_rps_send_master_info(1, "sendMasterInfo", "1.0");
            printf("rps_cmd_succ <<<--- rps = %s \n", rps);
            if(rps == NULL) {
                printf("rps_cmd_succ <<<--- rps is NULL get_rps_send_wifi_info failed ! \n");
                return 0;
            }
        }
        break;
        case 2: {
            rps = get_rps_send_wifi_info(2, "sendWifiInfo", "1.0");
            printf("rps_cmd_succ <<<--- rps = %s \n", rps);
            if(rps == NULL) {
                printf("rps_cmd_succ <<<--- rps is NULL get_rps_send_wifi_info failed ! \n");
                return 0;
            }
        }
        break;
        case 3: {
            rps = get_rps_modify_device_wifi(3, "modifyDeviceWifi", "1.0");
            printf("rps_cmd_succ <<<--- rps = %s \n", rps);
            if(rps == NULL) {
                printf("rps_cmd_succ <<<--- rps is NULL get_rps_modify_device_wifi failed ! \n");
                return 0;
            }
        }
        break;
        case 4: {
            rps = get_rps_get_device_ulist(4, "getDeviceUserList", "1.0");
            printf("rps_cmd_succ <<<--- rps = %s \n", rps);
            if(rps == NULL) {
                printf("rps_cmd_succ <<<--- rps is NULL get_rps_modify_device_wifi failed ! \n");
                return 0;
            }
        }
        break;
        case 5: {
            rps = get_rps_delete_device_user(5, "deleteDeviceUser", "1.0");
            printf("rps_cmd_succ <<<--- rps = %s \n", rps);
            if(rps == NULL) {
                printf("rps_cmd_succ <<<--- rps is NULL get_rps_modify_device_wifi failed ! \n");
                return 0;
            }
        }
        break;
        default:
            return 0;
    }

    int jdt_len = strlen(rps);
    dec_2_hex_big(jdt_len, rpsdt_jdtlen_buf, 4);

    rpsdt_len = 16 + jdt_len;
    rpsdt_buf = (char*) malloc(rpsdt_len);
    arr_char_pcpy(rpsdt_buf, 0, rpsdt_header_buf, 2);
    arr_char_pcpy(rpsdt_buf, 2, rpsdt_remain_buf, 10);
    arr_char_pcpy(rpsdt_buf, 12, rpsdt_jdtlen_buf, 4);
    arr_char_pcpy(rpsdt_buf, 16, rps, jdt_len);
//    prt_arr_char(rpsdt_buf, rpsdt_len, 1, "rps_do <<<--- rpsdt_buf = ", HEX_02X);

    int r = send(socket_conn_fd, rpsdt_buf, rpsdt_len, 0);
    printf("rps_cmd_succ <<<--- send socket_conn_fd r = %d \n", r);
    if(r < 0) {
        printf("rps_cmd_succ <<<--- send failed ! \n");
        return 0;
    }
    free(rpsdt_buf);

    printf("rps_cmd_succ --->>> \n");
    return 1;
}


/* distribute task */
int distrbt_cmd_do(int cmd_id, char* cmd_name, cJSON* cmd_param) {
    printf("distrbt_cmd_do <<<--- \n");
    printf("distrbt_cmd_do <<<--- cmd_id = %d \n", cmd_id);

    switch (cmd_id) {
        case 1: {
        		// response requery now
        	    if(!rps_cmd_succ(cmd_id)) {
        	        printf("distrbt_cmd_do <<<--- rps_cmd_succ failed ! cmd_id = %d \n", cmd_id);
        	        return 0;
        	    }
        	    // parse content and do
                cJSON* deviceMasterId = cJSON_GetObjectItem(cmd_param, "deviceMasterId");
                if(NULL == deviceMasterId) {
        	        printf("distrbt_cmd_do <<<--- NULL == deviceMasterId \n");
                    return 0;
                }
                int device_master_id = deviceMasterId->valueint;
//                if(device_master_id != *conf_user.device_master_id) {
//                	if(!write_user_master_id(deviceMasterId->valueint)) {
//						printf("distrbt_cmd_do <<<--- write_user_master_id failed ! \n");
//						return 0;
//					}
//				}
                // notify client success ...........................

            }
            break;
        case 2: {
                printf("distrbt_cmd_do <<<--- case 2: cmd_id = %d \n", cmd_id);
                // response requery now
				if(!rps_cmd_succ(cmd_id)) {
					printf("distrbt_cmd_do <<<--- rps_cmd_succ failed ! cmd_id = %d \n", cmd_id);
					return 0;
				}

                int device_master_id;
                char* device_user_mac;

                cJSON* device_master_id_cj = cJSON_GetObjectItem(cmd_param, "deviceMasterId");
                if(NULL == device_master_id_cj) {
                    printf("distrbt_cmd_do <<<--- case 2: device_master_id_cj == NULL \n");
                    return 0;
                }
                device_master_id = device_master_id_cj->valueint;
                printf("distrbt_cmd_do <<<--- delete_device_user device_master_id = %d \n", device_master_id);

                cJSON* wifi_list_cj = cJSON_GetObjectItem(cmd_param, "wifiList");
                if(NULL == wifi_list_cj) {
                    printf("distrbt_cmd_do <<<--- case 2: wifi_list_cj == NULL \n");
                    return 0;
                }

                int wifi_list_len = cJSON_GetArraySize(wifi_list_cj);

                int i = 0;
                for(; i < wifi_list_len; i++) {

                    printf("\n\n");

                    Wifilist wifi_list;


                    cJSON* wifi_list_sub_cj = cJSON_GetArrayItem(wifi_list_cj, i);


                    cJSON* wifi_id_cj = cJSON_GetObjectItem(wifi_list_sub_cj, "wifiId");
                    if(NULL == wifi_id_cj) {
                        printf("distrbt_cmd_do <<<--- case 2: wifi_id_cj == NULL \n");
                        return 0;
                    }
//                    printf("distrbt_cmd_do <<<--- case 2: wifi_id_cj != NULL \n");
                    wifi_list.wifi_id = wifi_id_cj->valueint;
                    printf("distrbt_cmd_do <<<--- send_wifi_info --->>> %d --->>> wifi_list.wifi_id = %d \n", i, wifi_list.wifi_id);


                    cJSON* wifi_master_id_cj = cJSON_GetObjectItem(wifi_list_sub_cj, "wifiMasterId");
                    if(NULL == wifi_master_id_cj) {
                        printf("distrbt_cmd_do <<<--- case 2: wifi_master_id_cj == NULL \n");
                        return 0;
                    }
//                    printf("distrbt_cmd_do <<<--- case 2: wifi_master_id_cj != NULL \n");
                    wifi_list.wifi_matser_id = wifi_master_id_cj->valueint;
                    printf("distrbt_cmd_do <<<--- send_wifi_info --->>> %d --->>> wifi_list.wifi_matser_id = %d \n", i, wifi_list.wifi_matser_id);


                    cJSON* wifi_ssid_cj = cJSON_GetObjectItem(wifi_list_sub_cj, "wifiSSID");
                    if(NULL == wifi_ssid_cj) {
                        printf("distrbt_cmd_do <<<--- case 2: wifi_ssid_cj == NULL \n");
                        return 0;
                    }
//                    printf("distrbt_cmd_do <<<--- case 2: wifi_ssid_cj != NULL \n");
                    stpcpy(wifi_list.wifi_ssid, wifi_ssid_cj->valuestring);
                    printf("distrbt_cmd_do <<<--- send_wifi_info --->>> %d --->>> wifi_list.wifi_ssid = %s \n", i, wifi_list.wifi_ssid);


                    cJSON* wifi_password_cj = cJSON_GetObjectItem(wifi_list_sub_cj, "wifiPassword");
                    if(NULL == wifi_password_cj) {
                        printf("distrbt_cmd_do <<<--- case 2: wifi_password_cj == NULL \n");
                        return 0;
                    }
//                    printf("distrbt_cmd_do <<<--- case 2: wifi_password_cj != NULL \n");
                    stpcpy(wifi_list.wifi_password, wifi_password_cj->valuestring);
                    printf("distrbt_cmd_do <<<--- send_wifi_info --->>> %d --->>> wifi_list.wifi_password = %s \n", i, wifi_list.wifi_password);


                    cJSON* wifi_mac_cj = cJSON_GetObjectItem(wifi_list_sub_cj, "wifiMac");
                    if(NULL == wifi_mac_cj) {
                        printf("distrbt_cmd_do <<<--- case 2: wifi_mac_cj == NULL \n");
                        return 0;
                    }
//                    printf("distrbt_cmd_do <<<--- case 2: wifi_mac_cj != NULL \n");
                    stpcpy(wifi_list.wifi_mac, wifi_mac_cj->valuestring);
                    printf("distrbt_cmd_do <<<--- send_wifi_info --->>> %d --->>> wifi_list.wifi_mac = %s \n", i, wifi_list.wifi_mac);


                    cJSON* wifi_longitude_cj = cJSON_GetObjectItem(wifi_list_sub_cj, "wifiLongitude");
                    if(NULL == wifi_longitude_cj) {
                        printf("distrbt_cmd_do <<<--- case 2: wifi_longitude_cj == NULL \n");
                        return 0;
                    }
//                    printf("distrbt_cmd_do <<<--- case 2: wifi_longitude_cj != NULL \n");
                    wifi_list.wifi_longitude = wifi_longitude_cj->valuedouble;
                    printf("distrbt_cmd_do <<<--- send_wifi_info --->>> %d --->>> wifi_list.wifi_longitude = %f \n", i, wifi_list.wifi_longitude);


                    cJSON* wifi_latitude_cj = cJSON_GetObjectItem(wifi_list_sub_cj, "wifiLatitude");
                    if(NULL == wifi_latitude_cj) {
                        printf("distrbt_cmd_do <<<--- case 2: wifi_latitude_cj == NULL \n");
                        return 0;
                    }
//                    printf("distrbt_cmd_do <<<--- case 2: wifi_latitude_cj != NULL \n");
                    wifi_list.wifi_latitude = wifi_latitude_cj->valuedouble;
                    printf("distrbt_cmd_do <<<--- send_wifi_info --->>> %d --->>> wifi_list.wifi_latitude = %f \n", i, wifi_list.wifi_latitude);


                    cJSON* wifi_area_id_cj = cJSON_GetObjectItem(wifi_list_sub_cj, "wifiAreaId");
                    if(NULL == wifi_area_id_cj) {
                        printf("distrbt_cmd_do <<<--- case 2: wifi_area_id_cj == NULL \n");
                        return 0;
                    }
//                    printf("distrbt_cmd_do <<<--- case 2: wifi_area_id_cj != NULL \n");
                    wifi_list.wifi_area_id = wifi_area_id_cj->valueint;
                    printf("distrbt_cmd_do <<<--- send_wifi_info --->>> %d --->>> wifi_list.wifi_area_id = %d \n", i, wifi_list.wifi_area_id);

                    // save wifi list data to db ..........................................................
                    SQ_DBInsert("wifidb1","wifilist",&wifi_list,1);
                }
                printf("\n\n");

                // do send_wifi_info ..........................................................

            }
            break;
        case 3: {
                printf("distrbt_cmd_do <<<--- case 3: cmd_id = %d \n", cmd_id);
                // response requery now
				if(!rps_cmd_succ(cmd_id)) {
					printf("distrbt_cmd_do <<<--- rps_cmd_succ failed ! cmd_id = %d \n", cmd_id);
					return 0;
				}
                int device_master_id;
                char* device_wifi_ssid;
                char* device_wifi_pwd;

                cJSON* device_master_id_cj = cJSON_GetObjectItem(cmd_param, "deviceMasterId");
                if(NULL == device_master_id_cj) {
                    printf("distrbt_cmd_do <<<--- case 3: device_master_id_cj == NULL \n");
                    rps_cmd_error(cmd_id, 10100, "sys error");// response error
                    return 0;
                }
                device_master_id = device_master_id_cj->valueint;

                cJSON* device_wifi_ssid_cj = cJSON_GetObjectItem(cmd_param, "wifiSSID");
                if(NULL == device_wifi_ssid_cj) {
                    printf("distrbt_cmd_do <<<--- case 3: device_wifi_ssid_cj == NULL \n");
                    rps_cmd_error(cmd_id, 10100, "sys error");// response error
                    return 0;
                }
                device_wifi_ssid = device_wifi_ssid_cj->valuestring;

                cJSON* device_wifi_pwd_cj = cJSON_GetObjectItem(cmd_param, "wifiPassword");
                if(NULL == device_wifi_pwd_cj) {
                    printf("distrbt_cmd_do <<<--- case 3: device_wifi_pwd_cj == NULL \n");
                    rps_cmd_error(cmd_id, 10100, "sys error");// response error
                    return 0;
                }
                device_wifi_pwd = device_wifi_pwd_cj->valuestring;

                printf("distrbt_cmd_do <<<--- modify_device_wifi device_master_id = %d \n", device_master_id);
                printf("distrbt_cmd_do <<<--- modify_device_wifi device_wifi_ssid = %s \n", device_wifi_ssid);
                printf("distrbt_cmd_do <<<--- modify_device_wifi device_wifi_pwd = %s \n", device_wifi_pwd);

//                if(device_master_id != *conf_user.device_master_id) {
//                    printf("distrbt_cmd_do <<<--- device_master_id error ! \n");
//                    rps_cmd_error(cmd_id, 10100, "device_master_id error");// response error
//                    return 0;
//                }

//                if(!write_user_device_wifi_ssid(device_wifi_ssid)) {
//                    printf("distrbt_cmd_do <<<--- write_user_device_wifi_ssid failed ! \n");
//                    rps_cmd_error(cmd_id, 10100, "sys error");// response error
//                    return 0;
//                }
//
//                if(!write_user_device_wifi_pwd(device_wifi_pwd)) {
//                    printf("distrbt_cmd_do <<<--- write_user_device_wifi_pwd failed ! \n");
//                    rps_cmd_error(cmd_id, 10100, "sys error");// response error
//                    return 0;
//                }
            }
            break;
        case 4: {

                int device_master_id;
                cJSON* device_master_id_cj = cJSON_GetObjectItem(cmd_param, "deviceMasterId");
                if(NULL == device_master_id_cj) {
                    printf("distrbt_cmd_do <<<--- case 4: device_master_id_cj == NULL \n");
                    return 0;
                }
//                    printf("distrbt_cmd_do <<<--- case 2: device_master_id_cj != NULL \n");
                device_master_id = device_master_id_cj->valueint;
                printf("distrbt_cmd_do <<<--- case 4: send_wifi_info --->>> device_master_id = %d \n", device_master_id);


                // do get_device_ulist ..........................................................

            }
            break;
        case 5: {
                printf("distrbt_cmd_do <<<--- case 4: cmd_id = %d \n", cmd_id);
                // response requery now
				if(!rps_cmd_succ(cmd_id)) {
					printf("distrbt_cmd_do <<<--- rps_cmd_succ failed ! cmd_id = %d \n", cmd_id);
					return 0;
				}

                int device_master_id;
                char* device_user_mac;

                cJSON* device_master_id_cj = cJSON_GetObjectItem(cmd_param, "deviceMasterId");
                if(NULL == device_master_id_cj) {
                    printf("distrbt_cmd_do <<<--- case 4: device_master_id_cj == NULL \n");
                    return 0;
                }
                device_master_id = device_master_id_cj->valueint;

                cJSON* device_user_mac_cj = cJSON_GetObjectItem(cmd_param, "userMac");
                if(NULL == device_user_mac_cj) {
                    printf("distrbt_cmd_do <<<--- case 4: device_user_mac_cj == NULL \n");
                    return 0;
                }
                device_user_mac = device_user_mac_cj->valuestring;

                printf("distrbt_cmd_do <<<--- delete_device_user device_master_id = %d \n", device_master_id);
                printf("distrbt_cmd_do <<<--- delete_device_user device_user_mac = %s \n", device_user_mac);

//                if(device_master_id != *conf_user.device_master_id) {
//                    printf("distrbt_cmd_do <<<--- device_master_id error ! \n");
//                    return 0;
//                }

                // do delete_device_user ..........................................................

            }
            break;
        default:
            return 0;
    }



    printf("pars_prt_cmddt --->>> \n");
    return 1;
}


int pars_prt_cmddt() {
    printf("pars_prt_cmddt <<<--- \n");

    if(cmddt_buf == NULL ) {
        return -1;
    }

    cJSON* cmd_jdt = cJSON_Parse(cmddt_buf);
    if(cmd_jdt == NULL ) {
        return -1;
    }
    printf("pars_prt_cmddt <<<--- cmd_jdt = %s \n", cmd_jdt);

    cJSON* jsonrpc = cJSON_GetObjectItem(cmd_jdt,"jsonrpc");
    if(NULL == jsonrpc) {
        return -1;
    }
    printf("pars_prt_cmddt <<<--- jsonrpc = %s\n",jsonrpc->valuestring);

    cJSON* method = cJSON_GetObjectItem(cmd_jdt,"method");
    if(NULL == method) {
        return -1;
    }
    printf("pars_prt_cmddt <<<--- method = %s\n",method->valuestring);

    cJSON* params = cJSON_GetObjectItem(cmd_jdt,"params");
    if(NULL == params) {
        return -1;
    }

    cJSON* id = cJSON_GetObjectItem(cmd_jdt,"id");
    if(NULL == jsonrpc) {
        return -1;
    }
    printf("pars_prt_cmddt <<<--- id = %d \n",id->valueint);

    // do diff task according to method_id
    distrbt_cmd_do(id->valueint, method->valuestring, params);

    printf("pars_prt_cmddt --->>> \n");
}


void pars_prt() {
    printf("pars_prt <<<--- \n");

    while(1) {
        printf("pars_prt <<<--- while(1) \n");
        int r = read_prt(prtdt_buf, prtdt_len);
        if(r == -1) {
            printf("pars_prt <<<--- read_prtcl failed error \n");
            rmdt_len = 0;// throw out invalid data
            break;
        } else if(r == -2) {
            printf("pars_prt <<<--- read_prtcl failed data miss \n");
            rmdt_len = 0;// throw out invalid data
            printf("pars_prt --->>> while(1) \n");
            break;
        } else if(r == 1) {
            printf("pars_prt <<<--- read_prt success \n");
            pars_prt_cmddt();
            if(rmdt_len < 16) {
                printf("pars_prt <<<--- rmdt_len < 16 ... save remain data rmdt_len = %d \n", rmdt_len);
                printf("pars_prt --->>> while(1) \n");
                break;
            } else {
                printf("pars_prt <<<--- rmdt_len >= 16 ... go on !!!!!!!!!!! rmdt_len = %d \n", rmdt_len);
                prtdt_len = rmdt_len;
                prtdt_buf = (char*)malloc(prtdt_len);
                if(prtdt_buf == NULL) {
                    printf("pars_prt <<<--- prtdt_buf malloc failed \n");
                }
                memcpy(prtdt_buf, rmdt_buf, rmdt_len);
            }
        } else if(r == 3) {
            printf("pars_prt <<<--- r == 3 \n");
            printf("pars_prt <<<--- rmdt_len < 16 ... save remain data rmdt_len = %d \n", rmdt_len);
            if(rmdt_len >= 1024) {
                printf("pars_prt <<<--- rmdt_len >= 1024 \n");
                printf("pars_prt --->>> while(1) \n");
                break;
            }
        }
    }

    printf("pars_prt --->>> \n");
}


int prepar_prtdt_buf() {
    printf("prepar_prtdt_buf <<<--- \n");

    if(rmdt_len > 0) {// exsit remain data
        prtdt_len = rmdt_len + recvdt_len;
        printf("prepar_prtdt_buf <<<--- prtdt_len = %d \n", prtdt_len);
        prtdt_buf = (char*)malloc(prtdt_len);
        if(prtdt_buf == NULL) {
            printf("prtdt_buf malloc failed \n");
            return -1;
        }
        memcpy(prtdt_buf, rmdt_buf, rmdt_len);// cpy data from rmdt_buf to prtdt_buf
        int i;
        for(i = 0;i < recvdt_len;i++) {
            prtdt_buf[i + rmdt_len] = recvdt_buf[i];// cpy push data from recvdt_buf to prtdt_buf
        }
    } else if(rmdt_len == 0) {// not exsit remain data
        prtdt_len = recvdt_len;
        prtdt_buf = (char*)malloc(prtdt_len);// malloc prtdt_buf accord to prtdt_len
        if(prtdt_buf == NULL) {
            printf("prtdt_buf malloc failed \n");
            return -1;
        }
        memcpy(prtdt_buf, recvdt_buf, recvdt_len);// cpy data from recvdt_buf to prtdt_buf
    } else if(rmdt_len < 0) {// error occur
        return -1;
    }

    printf("prepar_prtdt_buf --->>> \n");
    return 1;
}


int save_remain(char* buf, int buf_len) {
    printf("save_remain <<<--- \n");

    rmdt_buf = (char*)malloc(rmdt_len);
    if(rmdt_buf == NULL) {
        printf("save_remain <<<--- rmdt_buf malloc failed \n");
        return -1;
    }
    int i;
    for(i = 0;i < rmdt_len;i++) {
        rmdt_buf[i] = buf[buf_len - rmdt_len + i];
    }

    printf("save_remain --->>> \n");
    return 1;

}


int read_prtcl_header(char* buf, int buf_len) {
    printf("read_prtcl_header <<<--- \n");

    int i = 0;
    for(;i < buf_len;i++) {
        if(buf[i] == 0x00000006 && buf[i + 1] == 0xFFFFFFA1) {
            printf("read_prtcl_header --->>> \n");
            return i;
        }
    }

    printf("read_prtcl_header --->>> \n");
    return -1;

}


int read_prt_cmddt(char* buf, int buf_len) {
    printf("read_prt_cmddt <<<--- \n");


    char len_buf[4] = {buf[12], buf[13], buf[14], buf[15]};
    cmddt_len = get_int_big_byte(len_buf, 4);
    printf("read_prt_cmddt <<<--- cmddt_len = %d \n", cmddt_len);
    printf("read_prt_cmddt <<<--- buf_len = %d \n", buf_len);
    rmdt_len = buf_len - (cmddt_len + 16);
    printf("read_prt_cmddt <<<--- rmdt_len = %d \n", rmdt_len);
    if(rmdt_len < 0) {
        rmdt_len = buf_len;
        printf("read_prt_cmddt --->>> sorry data miss ! \n");
        return -2;
    }
    printf("read_prtcl_jdt --->>> data remain ! \n");
    cmddt_buf = (char*)malloc(cmddt_len);
    if(cmddt_buf == NULL) {
        printf("read_prt_cmddt <<<--- cmddt_buf malloc failed \n");
        return -1;
    }
    int i = 0;
    for(;i < cmddt_len;i++) {
        cmddt_buf[i] = buf[16 + i];
    }

    printf("read_prt_cmddt --->>> \n");
    return 1;

}


int read_prt(char* buf, int buf_len) {
    printf("read_prt <<<--- \n");

    printf("read_prt <<<--- buf_len = %d \n", buf_len);

    int header_pos;

    if(buf_len >= 16) {
        // read header
        header_pos = read_prtcl_header(buf, buf_len);
        if(header_pos < 0) {
            printf("read_prt <<<--- find header failed header_pos = %d \n", header_pos);
            return -1;
        }
        printf("read_prt <<<--- find header success header_pos = %d \n", header_pos);

        //get length in header
        char len_buf[4] = {buf[12], buf[13], buf[14], buf[15]};
        cmddt_len = get_int_big_byte(len_buf, 4);
        printf("read_prt <<<--- cmddt_len = %d \n", cmddt_len);
        // when receive data smaller than should be and save to remain
        if(header_pos + 16 + cmddt_len > buf_len) {
            printf("read_prt_cmddt <<<--- header_pos + 16 + cmddt_len > recvdt_len and cmddt_len should be = %d \n", header_pos + 16 + cmddt_len);
            rmdt_len = buf_len;
            int r = save_remain(buf, buf_len);
            if(r == -1) {
                return -1;
            }
            return 3;
        }
        printf("read_prt <<<--- receive data length is enough ! start parsing cmddt ! \n");




        // copy prt buffer
        int tmp_buf_len = buf_len - header_pos;
        printf("read_prt <<<--- buf_len = %d \n", buf_len);
        printf("read_prt <<<--- tmp_buf_len = %d \n", buf_len);

        char* tmp_buf = (char*)malloc(tmp_buf_len);
        if(tmp_buf == NULL) {
            printf("read_prt <<<--- tmp_buf malloc failed \n");
        }
        printf("read_prt <<<--- tmp_buf malloc success \n");
        int i;
        for(i = header_pos;i < buf_len;i++) {
            tmp_buf[i - header_pos] = buf[i];
        }
        prt_arr_char(tmp_buf, tmp_buf_len, 1, "read_prt <<<--- tmp_buf = \n", HEX_02x);

        // read cmd body data
        int r = read_prt_cmddt(tmp_buf, tmp_buf_len);

        if(r == -1) {
            printf("read_prt <<<--- read_prtcl_data failed  \n");
            return -1;
        } else if(r == -2) {
            printf("read_prt <<<--- read_prtcl_data failed miss data rmdt_len = %d \n", rmdt_len);
            int r = save_remain(tmp_buf, tmp_buf_len);
            if(r == -1) {
                return -1;
            }
            return -2;
        } else if(r == 1) {
            int r = save_remain(tmp_buf, tmp_buf_len);
            if(r == -1) {
                return -1;
            }
            return 1;
        }
    } else {
        printf("read_prt <<<--- buf_len < 16 \n");
        printf("read_prt --->>> \n");
        return -1;
    }
}


/* */
int init_socket() {
    printf("init_socket <<<--- \n");

    // first call socket function
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);

    // open socket error
    if (socket_fd < 0) {
      perror("open socket failed !");
      return -1;
    }

    // init sockaddr param
    bzero((char *) &socketaddr_server, sizeof(socketaddr_server));// initialize socket structure
    socketaddr_server.sin_family = AF_INET;
    socketaddr_server.sin_port = htons(SOCKET_SERVER_PORT);
    socketaddr_server.sin_addr.s_addr = htonl(INADDR_ANY);

    // bind the host address success return 0 failed return -1
    if(bind(socket_fd,(struct sockaddr *)&socketaddr_server,sizeof(socketaddr_server)) == -1) {
        perror("bind socket failed !");
        return -1;
    }

    // listen success return 0 failed return -1
    // start listening for the clients, here process will go in sleep mode and will wait for the incoming connection
    if(listen(socket_fd, SOCKET_CLIENT_NUM) == -1) {
        perror("listen socket failed !");
        return -1;
    }

    printf("init_socket --->>> \n");
}


int process() {
    printf("process <<<--- \n");

    while(1) {
        // recv data from socket
        recvdt_len = recv(socket_conn_fd, recvdt_buf, sizeof(recvdt_buf), 0);
        printf("process <<<--- recvdt_len = %d \n", recvdt_len);

        if(recvdt_len == 0) {
            printf("process <<<--- socket client closed ! \n");
            close(socket_conn_fd);
            break;
        } else if(recvdt_len == -1) {
            printf("process <<<--- socket error ! \n");
            close(socket_conn_fd);
            break;
        } else if(recvdt_len > 0) {
            printf("process <<<--- socket recv success ! \n");
            // prepare protocol data
            if(prepar_prtdt_buf() != 1) {
                printf("main <<<--- prepar_prtdt_buf failed ! \n");
                continue;
            }
            pars_prt();
        }
    }

    printf("process --->>> \n");
}


void start() {
    printf("start <<<--- \n");

    while(1) {
        // accept client connect success reurn >0 faled return -1
        socket_conn_fd = accept(socket_fd, (struct sockaddr*)&socketaddr_client, &socketaddr_client_len);
        if(socket_conn_fd < 0) {
            perror("accept failed !");
            break;
        }
        // process client requery
        process();

    }

    // closed socket
    close(socket_conn_fd);
    close(socket_fd);

    printf("start --->>> \n");
}

void welcome() {
    printf("\n\n\n");
    printf("welcome to wifishare ! happy everyday ! \n");
    printf("\n\n\n");
}


int test_main(void) {


	    // welcome
	  //  welcome();

	    // init app config
	 //   init_conf();

	    // init app env
	  //  init_env();

	    // init socket
	    init_socket();

	    // start do
	   // start();
	    pthread_t socket_thread;
	    int ret = pthread_create(&socket_thread,NULL,(void *)start,NULL);
	    if (ret != 0)
	    	printf("creat socket_thread failed\n");
	   // Wifilist_local *wifilist;
	   // int num =0;
	   // SQ_DBCreate("wifidb1","wifilist");
	  //  num = SQ_DBSelect("wifidb1","wifilist","SSID","F",wifilist);
	   // printf("receive the number of recode :%d \n",num);
	   // printf("the recode's ssid is :%s \n",wifilist[0].wifi_ssid);
      //  wifi_scan();
	  //  network_start(5);
      // network_analysis();



	    while(1);
	  printf("main --->>> \n");
	    return 0;
}

